﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using Dashboard.Models;
using Ionic.Zip;

namespace Dashboard.Models
{
    public class LogsManager : ILogsManager
    {
        private static LogsManager instance = new LogsManager();
        internal static ILogsManager Instance
        {
            get { return instance; }
        }

        private LogsManager()
        {

        }

        private const string pathToWinLogs = "C:\\Windows\\System32\\winevt\\Logs\\";
        private static Dictionary<string, string> namesOfLogs = new Dictionary<string, string>();
        private static Dictionary<string, int> selectedPaths = new Dictionary<string, int>();

        public Dictionary<string, int> GetLogs()
        {
            string[] paths = new string[System.Web.Configuration.WebConfigurationManager.AppSettings.Count - 5];//some strange hardcode over here. maybe you should find better section in web.config
            string currentPath = String.Empty;                                                                  //where you will keep your paths. in this way we have 5 initial setting in the end
            namesOfLogs = new Dictionary<string, string>();
            selectedPaths = new Dictionary<string, int>();

            for (int i = 0; i < paths.Length; i++)
            {
                currentPath = System.Web.Configuration.WebConfigurationManager.AppSettings.GetValues(i)[0];
                CheckPathForFileOrDirectory(currentPath);
                paths[i] = GetNameFromPath(currentPath);
                namesOfLogs.Add(paths[i], currentPath);
            }

            return selectedPaths;
        }

        public List<EventLog> GetEventLogs()
        {
            EventLog[] eventLogsArray = EventLog.GetEventLogs();
            List<EventLog> listOfLogs = new List<EventLog>();

            for (int i = 0; i < eventLogsArray.Length; i++)
            {
                listOfLogs.Add(eventLogsArray[i]);
            }

            return listOfLogs;
        }

        public FilePathInfo GetEventLog(string log)
        {
            //return new FilePathInfo(String.Concat(pathToWinLogs, log), "application/octet-stream", log); that would work only with special rights. should work on it
            return new FilePathInfo("", "", "");         //should return this only in case of mistake
        }

        public FilePathInfo GetPathLog(string log)
        {
            if (String.IsNullOrEmpty(log))
            {
                throw new ArgumentException("name of log is null or empty");
            }
            if (String.IsNullOrEmpty(namesOfLogs[log]))
            {
                throw new ArgumentException("log does not exist");
            }

            return new FilePathInfo(namesOfLogs[log], "application/octet-stream", log);
        }

        public FilePathInfo CreateZipFolder(string id)
        {
            if (String.IsNullOrEmpty(id))
            {
                throw new ArgumentException("name of folder is null or empty");
            }
            if (String.IsNullOrEmpty(namesOfLogs[id]))
            {
                throw new ArgumentException("folder does not exist");
            }
            string directoryToCompress = namesOfLogs[id];
            //string tempDirectory = Environment.GetEnvironmentVariable("temp");
            string directoryToSave = String.Concat(namesOfLogs[id], ".zip");         //we should save file to temp directory of user as in example higher.
            ZipFile zip = new ZipFile();                                             //the question - how to clear this folder and when?
            zip.AddDirectory(directoryToCompress);

            try
            {
                zip.Save(directoryToSave);
            }
            catch (Exception e)
            {
                return new FilePathInfo("", "", "");
            }

            return new FilePathInfo(directoryToSave, "application/octet-stream", String.Concat(id, ".zip"));
        }

        public static string GetNameFromPath(string path)
        {
            string name = String.Empty;
            int pos = 0;

            for (int i = path.Length - 1; i > 0; i--)
            {
                if (path[i] == '\\')
                {
                    pos = i + 1;
                    break;
                }
            }

            for (int j = pos; j < path.Length; j++)
            {
                name += path[j];
            }

            return name;
        }

        private static void CheckPathForFileOrDirectory(string currentPath)
        {
            if (!(File.Exists(currentPath) || Directory.Exists(currentPath)))
            {
                selectedPaths.Add(currentPath, 2);                      //means non-existing path
            }
            else
            {
                FileAttributes attributes = File.GetAttributes(currentPath);
                if (attributes == FileAttributes.Directory)
                {
                    selectedPaths.Add(currentPath, 0);                  //directory path
                }
                else
                {
                    selectedPaths.Add(currentPath, 1);                  //path to the file
                }
            }
        }
    }
}